package com.whmall.service.crm.module.company.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.whmall.component.service.AbstractDbService;
import com.whmall.service.crm.entity.dto.company.CompanyConfigDTO;
import com.whmall.service.crm.enumeration.CompanyConfigKeyEnum;
import com.whmall.service.crm.module.company.dao.CompanyConfigMapper;
import com.whmall.service.crm.module.company.entity.CompanyConfigDO;
import com.whmall.service.crm.module.company.service.CompanyConfigService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 公司配置表 服务实现类
 * </p>
 *
 * @author yjh
 * @since 2023-03-23
 */
@Service
public class CompanyConfigServiceImpl extends AbstractDbService<CompanyConfigMapper, CompanyConfigDO> implements CompanyConfigService {

    /**
     * 根据key查询单位下的配置
     *
     * @param key
     * @param companyId 单位id
     * @return
     */
    @Override
    public CompanyConfigDTO getByKey(String key, Long companyId) {
        LambdaQueryWrapper<CompanyConfigDO> qw = new LambdaQueryWrapper<>();
        qw.eq(CompanyConfigDO::getCompanyId, companyId).eq(CompanyConfigDO::getKey, key);
        CompanyConfigDO companyConfigDO = this.getBaseMapper().selectOne(qw);
        if (companyConfigDO == null) {
            return null;
        }
        CompanyConfigDTO companyConfigDTO = new CompanyConfigDTO();
        BeanUtils.copyProperties(companyConfigDO, companyConfigDTO);
        return companyConfigDTO;
    }

    @Override
    public List<CompanyConfigDTO> findByKey(String key) {
        return this.baseMapper.selectList(new QueryWrapper<CompanyConfigDO>().lambda()
                        .eq(CompanyConfigDO::getKey, key)).stream()
                .map(c -> BeanUtil.copyProperties(c, CompanyConfigDTO.class))
                .collect(Collectors.toList());
    }

    @Override
    public List<CompanyConfigDTO> findByKey(String key, Collection<Long> companyIds) {
        if (CollectionUtils.isEmpty(companyIds)) {
            return Collections.emptyList();
        }
        return this.baseMapper.selectList(new QueryWrapper<CompanyConfigDO>().lambda()
                        .in(CompanyConfigDO::getCompanyId, companyIds)
                        .eq(CompanyConfigDO::getKey, key)).stream()
                .map(c -> BeanUtil.copyProperties(c, CompanyConfigDTO.class))
                .collect(Collectors.toList());
    }

    @Override
    public Map<String, String> getConfig(Long companyId, Collection<String> keys) {
        if (CollectionUtils.isEmpty(keys)) {
            return Collections.emptyMap();
        }
        Map<String, String> configs = baseMapper.selectList(new QueryWrapper<CompanyConfigDO>().lambda()
                .eq(CompanyConfigDO::getCompanyId, companyId)
                .in(CompanyConfigDO::getKey, keys)).stream().collect(Collectors.toMap(CompanyConfigDO::getKey, CompanyConfigDO::getValue, (a, b) -> a));
        for (String key : keys) {
            if (configs.containsKey(key)) {
                continue;
            }
            configs.put(key, Optional.ofNullable(CompanyConfigKeyEnum.fromValue(key)).map(CompanyConfigKeyEnum::getDefaultValue).orElse(null));
        }
        return configs;
    }

    @Override
    public Map<Long, Map<String, String>> getConfig(Collection<Long> companyIds, Collection<CompanyConfigKeyEnum> keys) {
        if (CollectionUtils.isEmpty(companyIds) || CollectionUtils.isEmpty(keys)) {
            return Collections.emptyMap();
        }
        Map<Long, Map<String, String>> companyMap = baseMapper.selectList(new QueryWrapper<CompanyConfigDO>().lambda()
                .in(CompanyConfigDO::getCompanyId, companyIds)
                .in(CompanyConfigDO::getKey, keys)).stream().collect(Collectors.groupingBy(CompanyConfigDO::getCompanyId,
                Collectors.toMap(CompanyConfigDO::getKey, CompanyConfigDO::getValue)));
        for (Long companyId : companyIds) {
            Map<String, String> companyKeyMap = companyMap.computeIfAbsent(companyId, k -> new HashMap<>());
            for (CompanyConfigKeyEnum key : keys) {
                companyKeyMap.putIfAbsent(key.getName(), key.getDefaultValue());
            }
        }
        return companyMap;
    }

    @Override
    public String getValue(Long companyId, CompanyConfigKeyEnum key) {
        Assert.isTrue(companyId != null, "参数缺失");
        Assert.isTrue(key != null, "参数缺失");
        CompanyConfigDO config = this.baseMapper.selectOne(new LambdaQueryWrapper<CompanyConfigDO>()
                .eq(CompanyConfigDO::getCompanyId, companyId)
                .eq(CompanyConfigDO::getKey, key.getName()));
        if (config == null) {
            return key.getDefaultValue();
        }
        return config.getValue();
    }
}
